Skip to content

AsyncAPI 3.x: publish a message's examples, some of the time - #1754

Open
LautaroPetaccio wants to merge 2 commits into
masterfrom
feature/asyncapi-examples
Open

LautaroPetaccio wants to merge 2 commits into
masterfrom
feature/asyncapi-examples

Conversation

@LautaroPetaccio

@LautaroPetaccio LautaroPetaccio commented Sep 13, 2026 •

Copy link
Copy Markdown
Collaborator

Why

A message's examples are what the document's author knows the service accepts. A service that silently drops what it does not recognise — the normal behaviour of a Kafka consumer or a WebSocket handler faced with a malformed message — may never reply to a payload sampled from the schema alone, and a search that never sees a reply never gets to tell the reply variants apart. Publishing the author's example some of the time is the cheapest way to make sure the search starts from something that works.

What it does

With --probAsyncApiExamples p (@Experimental, 0 by default), each example a message declares is offered as a whole payload beside the schema-derived genes, picked with probability p. A named example keeps its name, so probNamedExamples works for it as it does for REST. Headers examples are handled the same way, minus the correlation-id field the headers gene does not have either.

How

REST already builds a ChoiceGene between a caller-supplied list of named examples and the schema-derived genes, weighted by probUseExamples. createGeneForDTO takes that list as a trailing parameter, defaulted empty, and AsyncApiGeneBuilder passes every message example through it. The examples go beside the schema rather than into it because the OpenAPI 3.0 wrapper the genes are built through keeps only one example, drops names, and warns about one on a scalar.

Two details:

  • Examples are dropped when probUseExamples is zero, as REST does, instead of building a choice weighted at zero.
  • Built genes are cached by schema text, so a call with examples bypasses the cache: two messages can share a schema and differ in examples.

The TODO in AsyncApiSampler is removed.

Testing

AsyncApiGeneBuilderTest, AsyncApiSamplerTest and RestActionBuilderV3Test cover every example being offered, including on a scalar payload; a name reaching the action's named-example lookup; a headers example losing the correlation field; nothing changing shape at probability zero; and two messages sharing a schema keeping their own examples.

All AsyncAPI suites plus RestActionBuilderV3Test: 258 tests, 0 failures, 2 skipped.

@LautaroPetaccio
LautaroPetaccio added this pull request to stack #1712 September 13, 2026 21:33
@LautaroPetaccio
LautaroPetaccio marked this pull request as ready for review September 13, 2026 21:34
@LautaroPetaccio
LautaroPetaccio marked this pull request as draft September 13, 2026 21:35
@arcuri82
arcuri82 force-pushed the feature/asyncapi-examples branch from f2b10c8 to 5d3566d Compare September 14, 2026 10:51
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 5d3566d to 66440f3 Compare September 14, 2026 22:17
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 66440f3 to 179e5d3 Compare September 15, 2026 16:29
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch 2 times, most recently from 2495b28 to 82d1889 Compare September 16, 2026 01:16
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 82d1889 to 18be100 Compare September 16, 2026 21:57
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 18be100 to d945333 Compare September 16, 2026 22:01
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from d945333 to 12d8d09 Compare September 19, 2026 23:03
@LautaroPetaccio LautaroPetaccio changed the title AsyncAPI 3.x: publish a message's example, some of the time AsyncAPI 3.x: publish a message's examples, some of the time Sep 20, 2026
@LautaroPetaccio
LautaroPetaccio marked this pull request as ready for review September 20, 2026 22:27
@arcuri82
arcuri82 force-pushed the feature/asyncapi-examples branch from d03cbf6 to 24d85cc Compare September 22, 2026 11:05
@jgaleotti

Copy link
Copy Markdown
Collaborator

@LautaroPetaccio this PR seems to have all the same changes as #1753.

@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 24d85cc to 5e7d833 Compare September 23, 2026 17:56
@arcuri82
arcuri82 force-pushed the feature/asyncapi-examples branch from 5e7d833 to d9cc67e Compare September 24, 2026 07:27
@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from d9cc67e to 0b05618 Compare September 24, 2026 14:55
@LautaroPetaccio

Copy link
Copy Markdown
Collaborator Author

Yes! it needed rebasing @jgaleotti. It's now rebased with the latest changes, so you'll see now only the latest changes.

@LautaroPetaccio
LautaroPetaccio force-pushed the feature/asyncapi-examples branch from 0b05618 to 71ff389 Compare September 25, 2026 20:14
Base automatically changed from feature/asyncapi-fitness to master September 28, 2026 08:35
A document's message examples are what its author knows the service
accepts. A service that silently drops what it does not recognise may
never answer a sampled payload, so with --probAsyncApiExamples the first
example of a message is offered as a whole value beside the schema-derived
genes, at that probability. Off by default, like every new feature.

It reuses what REST already does with a schema's 'example': the example is
put on the message's own copy of the payload schema, and the gene builder
turns it into the same choice it offers REST. Only the first example is
used: the OpenAPI parser the genes go through reads the schemas as 3.0,
which drops the plural 'examples'. Scalars are left alone, as the builder
would complain about 'example' on them. A headers example loses the field
the correlation id is stamped into, as the headers gene did before it.
The first cut wrote one example into the message's copy of its payload
schema and let the gene builder find it there. That path crosses the
OpenAPI parser, which keeps only the first of several, drops the name an
example may carry, and warns about an example on a scalar. So only one
example was offered, never by name, and never for a scalar payload.

The gene builder already takes examples the other way, as a list of values
with optional names, for a REST parameter or request body. Its entry point
for a bare schema simply did not expose that parameter. It does now, with
an empty default so that no other caller changes, and the AsyncAPI builder
passes every example through it: all of them are offered, a name survives
to where the sampler's named-example pass can read it, and a scalar
payload gets the same choice an object does.

One trap came with it. The builder caches what it builds by schema text
alone, so two messages sharing a schema but declaring different examples
would have been handed the same gene. A call that brings examples now
neither reads nor writes that cache.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants